package tomkitty.turdlet;

import tomkitty.server.*;
import tomkitty.util.*;
import java.util.*;
import java.io.*;
import java.text.*;

public class StaticTurdlet extends TurdletBase implements HttpConstants {

	protected static Hashtable<String,String> cache = 
		new Hashtable<String,String>();

	private String reqFile, docRoot;
	
	//8kb buffer size - used when files are longer than this
	private final int buff_size = 8192;

	protected void setContentType(File file) {

		String filePath;

		try {
			filePath = file.getCanonicalPath();
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}

		String mime = cache.get(filePath);

		if (mime == null) {
			mime = "text/plain";

			try {

				String argv[] = {"file", "-bi", filePath};
				Process proc = 
					Runtime.getRuntime().exec(argv);
				BufferedReader br = 
					new BufferedReader(new InputStreamReader(proc.getInputStream()));
				mime = br.readLine();
				cache.put(filePath, mime);
				br.close();

			} catch (Exception e) {

			}
		}
		
		// this is because FF at least wants to download all kinds of text. dumb.
		if (mime.substring(0, 6).equals("text/x")) {
			mime = "text/plain";
		}

		setContentType(mime);
	}

	public void doit() {
		reqFile = getContext().getRequest().getUri().getPath();
		docRoot = Main.getConfig().get("docroot");
		String dflFile = Main.getConfig().get("default_file");

		if (docRoot == null) {
			Debug.e("can't serve static pages: no docroot specified");
			return;
		}

		if (dflFile == null) {
			dflFile = "";
		}

		TurdletFactory factory = getContext().getHandler().getFactory();
		try {

			File file;
			
			if (! (file = new File(docRoot + reqFile + dflFile)).exists() &&
					! (file = new File(docRoot + reqFile)).exists() ) {
				factory.runTurdlet(factory.NotFoundError(getContext()));
				return;
			}
		
			if (file.isDirectory()) {
				dirList(file);
			} else if (file.canRead()) {
				int len = (int)file.length();
				
				setContentType(file);
				setContentLength(len);

				BufferedInputStream br = new BufferedInputStream(new FileInputStream (file));
				
				byte[] buffer;
				//file size is less than buffer, not buffering
				if(len < buff_size) {
					buffer = new byte[len];
					br.read(buffer, 0, len);
					write(buffer, 0, len);
				} else {
					//dealing with a file bigger than buffer size, buffering
					buffer = new byte[buff_size];
					while(br.read(buffer, 0, buff_size) != -1) {
						write(buffer, 0, buff_size);
					}
				}
				
				br.close ();
			} else {
				factory.runTurdlet(factory.ForbiddenError(getContext()));
			}

		} catch (Exception e) {

			e.printStackTrace();
			factory.runTurdlet(factory.ServerError(getContext()));

		}

	}

	protected void dirList(File dir) {

		try {

			String dirPath = dir.getCanonicalPath();
			TurdletFactory factory = getContext().getHandler().getFactory();

			if (reqFile.charAt(reqFile.length() - 1) != '/') {
				factory.runTurdlet(factory.RedirectError(getContext(), reqFile + "/"));
				return;
			}

			String[] list = dir.list();

			String path = getContext().getRequest().getUri().getPath();
			DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
					DateFormat.MEDIUM);

			print("<html><head>");
			print("<title>Directory Listing - " + path + "</title>");
			print("<style type=\"text/css\">");
			print("a {text-decoration: none; font-family: monospace;}");
			print("body {text-decoration: none; font-family: monospace;}");
			print("</style>");
			print("</head>");
			print("<body>");

			print("<h1>" + path + "</h1>\n");

			print("<table width=\"100%\">");
			print("<tr>");
			print("<th>Name</th><th>Size</th><th>Last Modified</th>");
			print("</tr>");

			if (! dirPath.equals(Main.getConfig().get("docroot"))) {
				print("<tr>");
				print("<td><a href=\"..\">../</a></td>");
				print("</tr>");
			}

			for(int i = 0; i < list.length; i++) {
				File f = new File(dir, list[i]);
				String hide = Main.getConfig().get("list_hidden_files");

				if (hide == null) {
					hide = "false";
				}

				print("<tr>");
				if(f.isDirectory()) {
					print("<td><a href=\""+list[i]+"/\">"+list[i]+"/</a></td>");
					print("<td align=\"right\">&lt;DIR&gt;</td>");
					print("<td align=\"right\">");
					print(df.format(new Date(f.lastModified())));
					print("</td>");
				} else if (! f.isHidden() || hide.toLowerCase().equals("true")) {
					print("<td><a href=\""+list[i]+"\">"+list[i]+"</a></td>");
					print("<td align=\"right\">");
					print(new Long(f.length()).toString());
					print("</td>");
					print("<td align=\"right\">");
					print(df.format(new Date(f.lastModified())));
					print("</td>");
				}
				print("</tr>");
			} 
			print("</table>");
			print("</body></html>");

		} catch (IOException e) {

			e.printStackTrace();

		}

	}
}

